package com.example.mqttclient;

import androidx.appcompat.app.AppCompatActivity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.Color;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.Switch;
import android.widget.TextView;
import com.example.mqttclient.mqtt.MqttService;
import com.example.mqttclient.protocol.AirConditioningMessage;
import com.example.mqttclient.protocol.BoolMessage;
import com.example.mqttclient.protocol.FloatMessage;
import com.example.mqttclient.protocol.IntMessage;
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.formatter.ValueFormatter;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import org.eclipse.paho.client.mqttv3.MqttException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class DevicesDemoActivity extends AppCompatActivity implements MqttService.MqttEventCallBack,
        CompoundButton.OnCheckedChangeListener {

    private TextView connectState, doorStatus;
    private EditText airConditioningValue;
    private MqttService.MqttBinder mqttBinder;
    private String TAG = "DevicesDemoActivity";
    private Switch parlourLightSwitch, curtainSwitch, fanSocketSwitch, airConditioningSwitch;
    private Map<String, Integer> subscribeTopics = new HashMap<>();
    // 图表相关
    private LineChart temperatureChart, humidityChart, pmChart, gasChart;
    private static final int MAX_DATA_POINTS = 20;
    private boolean[] hasData = {false, false, false, false}; // 分别对应4个图表

    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            mqttBinder = (MqttService.MqttBinder) iBinder;
            mqttBinder.setMqttEventCallBack(DevicesDemoActivity.this);
            if (mqttBinder.isConnected()) {
                connectState.setText("已连接");
                subscribeTopics();
            } else {
                connectState.setText("未连接");
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_devices_demo);
        // 初始化视图
        connectState = findViewById(R.id.dev_connect_state);
        doorStatus = findViewById(R.id.door_status);
        airConditioningValue = findViewById(R.id.air_conditioning_value);
        // 初始化开关
        parlourLightSwitch = findViewById(R.id.parlour_light_switch);
        curtainSwitch = findViewById(R.id.curtain_switch);
        fanSocketSwitch = findViewById(R.id.fan_socket_switch);
        airConditioningSwitch = findViewById(R.id.air_conditioning_switch);
        // 设置开关监听
        parlourLightSwitch.setOnCheckedChangeListener(this);
        curtainSwitch.setOnCheckedChangeListener(this);
        fanSocketSwitch.setOnCheckedChangeListener(this);
        airConditioningSwitch.setOnCheckedChangeListener(this);
        // 初始化图表
        temperatureChart = findViewById(R.id.temperature_chart);
        humidityChart = findViewById(R.id.humidity_chart);
        pmChart = findViewById(R.id.pm_chart);
        gasChart = findViewById(R.id.gas_chart);
        // 初始化图表
        setupChart(temperatureChart, "温度", Color.RED, 0);
        setupChart(humidityChart, "湿度", Color.BLUE, 1);
        setupChart(pmChart, "PM2.5", Color.GREEN, 2);
        setupChart(gasChart, "气体", Color.YELLOW, 3);
        // 绑定MQTT服务
        Intent mqttServiceIntent = new Intent(this, MqttService.class);
        bindService(mqttServiceIntent, connection, Context.BIND_AUTO_CREATE);
    }

    private void setupChart(LineChart chart, String label, int color, int chartIndex) {
        // 获取Y轴实例
        YAxis leftAxis = chart.getAxisLeft();
        // 根据图表类型设置不同范围
        switch(chartIndex) {
            case 0: // 温度图表（°C）
                leftAxis.setAxisMinimum(-10f);
                leftAxis.setAxisMaximum(50f);
                break;
            case 1: // 湿度图表（%）
                leftAxis.setAxisMinimum(0f);
                leftAxis.setAxisMaximum(100f);
                break;
            case 2: // PM2.5图表（μg/m³）
                leftAxis.setAxisMinimum(0f);
                leftAxis.setAxisMaximum(500f);
                break;
            case 3: // 气体图表（%LEL）
                leftAxis.setAxisMinimum(0f);
                leftAxis.setAxisMaximum(100f);
                break;
        }
        // 其他图表配置保持不变...
        leftAxis.setEnabled(false); // 初始禁用
        leftAxis.setTextSize(10f);

        // 禁用右侧Y轴
        YAxis rightAxis = chart.getAxisRight();
        rightAxis.setEnabled(false);

        // 图例设置
        Legend legend = chart.getLegend();
        legend.setTextSize(10f);
        legend.setFormSize(10f);

        // 设置无数据提示
        chart.setNoDataText("等待数据中...");
        chart.setNoDataTextColor(Color.GRAY);

        // 创建空数据
        LineDataSet dataSet = new LineDataSet(new ArrayList<>(), label);
        dataSet.setColor(color);
        dataSet.setCircleColor(color);
        dataSet.setLineWidth(1.5f);
        dataSet.setCircleRadius(2f);
        dataSet.setDrawCircleHole(false);
        dataSet.setValueTextSize(8f);
        dataSet.setDrawValues(true); // 显示数据点的值

        // 设置小数格式
        DecimalFormat df = new DecimalFormat("0.00");
        dataSet.setValueFormatter(new ValueFormatter() {
            @Override
            public String getFormattedValue(float value) {
                return df.format(value);
            }
        });

        // 关键修改：设置X轴粒度和范围
        XAxis xAxis = chart.getXAxis();
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        xAxis.setGranularity(1f); // 强制刻度间隔为1
        xAxis.setAxisMinimum(0f); // X轴最小值从0开始
        xAxis.setValueFormatter(new ValueFormatter() {
            @Override
            public String getFormattedValue(float value) {
                return String.valueOf((int) value); // 显示为整数
            }
        });

        LineData lineData = new LineData(dataSet);
        chart.setData(lineData);
        chart.invalidate();
    }

    private void addEntry(LineChart chart, float value, int chartIndex) {
        LineData data = chart.getData();
        if (data != null) {
            LineDataSet set = (LineDataSet) data.getDataSetByIndex(0);
            if (set == null) {
                set = new LineDataSet(new ArrayList<>(), "数据");
                set.setColor(getColorByChartIndex(chartIndex));
                data.addDataSet(set);
            }

            // 第一次收到数据时启用坐标轴
            if (!hasData[chartIndex]) {
                chart.getXAxis().setEnabled(true);
                chart.getAxisLeft().setEnabled(true);
                hasData[chartIndex] = true;
            }

            // 限制数据点数量
            if (set.getEntryCount() >= MAX_DATA_POINTS) {
                set.removeFirst(); // 移除最早的数据点
                // 更新剩余数据点的X值为连续整数（0,1,2,...）
                for (int i = 0; i < set.getEntryCount(); i++) {
                    set.getEntryForIndex(i).setX(i); // 重置X值为索引
                }
            }

            // 添加新数据点，X值为当前数据点数量（自动递增的整数）
            data.addEntry(new Entry(set.getEntryCount(), value), 0);
            data.notifyDataChanged();
            chart.notifyDataSetChanged();

            // 调整可见范围，确保X轴从0开始显示
            chart.setVisibleXRangeMaximum(MAX_DATA_POINTS);
            chart.moveViewToX(data.getEntryCount()); // 滚动到最新数据点（不减去1，避免显示不全）
        }
    }

    // 辅助方法：根据图表索引获取颜色
    private int getColorByChartIndex(int chartIndex) {
        int[] colors = {Color.RED, Color.BLUE, Color.GREEN, Color.YELLOW};
        return colors[chartIndex % colors.length];
    }

    @Override
    public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
        switch (compoundButton.getId()) {
            case R.id.parlour_light_switch:
                try {
                    mqttBinder.publishMessage("/test/light1",
                            new Gson().toJson(new BoolMessage(b)));
                } catch (MqttException e) {
                    e.printStackTrace();
                }
                break;
            case R.id.curtain_switch:
                try {
                    mqttBinder.publishMessage("/test/curtain1",
                            new Gson().toJson(new BoolMessage(b)));
                } catch (MqttException e) {
                    e.printStackTrace();
                }
                break;
            case R.id.fan_socket_switch:
                try {
                    mqttBinder.publishMessage("/test/fan1",
                            new Gson().toJson(new BoolMessage(b)));
                } catch (MqttException e) {
                    e.printStackTrace();
                }
                break;
            case R.id.air_conditioning_switch:
                try {
                    String json = new Gson().toJson(new AirConditioningMessage(b,
                            Float.parseFloat(airConditioningValue.getText().toString())));
                    mqttBinder.publishMessage("/test/airConditioning", json);
                } catch (MqttException e) {
                    e.printStackTrace();
                }
                break;
        }
    }

    @Override
    public void onMqttMessage(String topic, String message) {
        Log.d("onMqttMessage", "topic:" + topic + " message:" + message);
        Gson gson = new Gson();
        switch (subscribeTopics.get(topic)) {
            case 1: // 温度
                JsonObject tempJson = gson.fromJson(message, JsonObject.class);
                float tempValue = tempJson.get("value").getAsFloat();
                runOnUiThread(() -> addEntry(temperatureChart, tempValue, 0));
                break;
            case 2: // 湿度
                JsonObject humJson = gson.fromJson(message, JsonObject.class);
                int humValue = humJson.get("value").getAsInt();
                runOnUiThread(() -> addEntry(humidityChart, humValue, 1));
                break;
            case 3: // PM2.5
                JsonObject pmJson = gson.fromJson(message, JsonObject.class);
                int pmValue = pmJson.get("value").getAsInt();
                runOnUiThread(() -> addEntry(pmChart, pmValue, 2));
                break;
            case 4: // 气体
                JsonObject gasJson = gson.fromJson(message, JsonObject.class);
                int gasValue = gasJson.get("value").getAsInt();
                runOnUiThread(() -> {
                    addEntry(gasChart, gasValue, 3);
                    // 如果单独保留数值显示
                    // gasValueText.setText(String.valueOf(gasValue));
                });
                break;
            case 5: // 门状态
                String status = gson.fromJson(message.trim(), BoolMessage.class).value ? "开" : "关";
                runOnUiThread(() -> doorStatus.setText(status));
                break;
        }
    }

    // ...保持其他方法不变（subscribeTopics、unSubscribeTopics等）...
    // 以下是未修改的方法，保持原有实现
    void subscribeTopics() {
        try {
            subscribeTopics.put("/test/temp", 1);
            subscribeTopics.put("/test/hum", 2);
            subscribeTopics.put("/test/pm", 3);
            subscribeTopics.put("/test/gas", 4);
            subscribeTopics.put("/test/door", 5);
            for (Map.Entry<String, Integer> entry : subscribeTopics.entrySet()) {
                mqttBinder.subscribe(entry.getKey());
            }
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }

    void unSubscribeTopics() {
        try {
            for (Map.Entry<String, Integer> entry : subscribeTopics.entrySet()) {
                mqttBinder.unSubscribe(entry.getKey());
            }
            subscribeTopics.clear();
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onConnectSuccess() {
        runOnUiThread(() -> {
            connectState.setText("已连接");
            subscribeTopics();
        });
    }

    @Override
    public void onConnectError(String error) {
        Log.d(TAG, "onConnectError: " + error);
        runOnUiThread(() -> {
            connectState.setText("未连接");
            subscribeTopics.clear();
        });
    }

    @Override
    public void onDeliveryComplete() {
        Log.d(TAG, "publish ok");
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        if (mqttBinder != null && mqttBinder.isConnected()) {
            connectState.setText("已连接");
            subscribeTopics();
        } else {
            connectState.setText("未连接");
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        unSubscribeTopics();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mqttBinder != null) {
            unbindService(connection);
        }
    }
}